﻿Copyright
 * / *(C) 2009-2010 adrian_007, adrian-007 on o2 point pl
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See tehT
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "stdinc.h"
#include "Manager.h"

using std::wstring;

#define LOG(x) __LOG(wtw, L"WHID", x) 

#define MENU_ITEM_ID_CONVERT	L"wtwChatBot/convertArchive"
#define MENU_ITEM_NAME_CONVERT	L"Konwertuj archiwum"

#define MENU_ITEM_ID_START	 L"wtwChatBot/startBot"
#define MENU_ITEM_NAME_START L"Uruchom bota"

#define MENU_ITEM_ID_STOP	L"wtwChatBot/stopBot"
#define MENU_ITEM_NAME_STOP	L"Zatrzymaj bota"
#define PAGE_NAME L"Opcje"


Manager::Manager(HINSTANCE hInst) : hInstance(hInst), chatHook(0)
{
	initStartActions();
	initSettings();
	initOptions();
	humour = "";
}

void Manager::initSettings()
		{
		wtwMyConfigFile pBuff;
		initStruct(pBuff);

		pBuff.bufferSize = MAX_PATH + 1;
		pBuff.pBuffer = new wchar_t[MAX_PATH + 1];
		pBuff.desiredExt = L"config";
		memset(pBuff.pBuffer, 0, pBuff.bufferSize);

		wtw->fnCall(WTW_SETTINGS_GET_MY_CONFIG_FILE, reinterpret_cast<WTW_PARAM>(&pBuff), reinterpret_cast<WTW_PARAM>(hInstance));
		config = reinterpret_cast<void*>(wtw->fnCall(WTW_SETTINGS_INIT, reinterpret_cast<WTW_PARAM>(pBuff.pBuffer), reinterpret_cast<WTW_PARAM>(hInstance)));
		wtw->fnCall(WTW_SETTINGS_READ, reinterpret_cast<WTW_PARAM>(config), 0);
		delete[] pBuff.pBuffer;
}

Manager::~Manager(void)
{
	if(chatHook != 0)
		wtw->evUnhook(chatHook);
	wtw->fnCall(WTW_MENU_FUNCTION_CLR, reinterpret_cast<WTW_PARAM>(hInstance), 0);
	// zapisujemy ustawienia
	wtw->fnCall(WTW_SETTINGS_WRITE, reinterpret_cast<WTW_PARAM>(config), 0);
	// czyscimy pamiec i zamykamy plik ustawien
	wtw->fnCall(WTW_SETTINGS_DESTROY, reinterpret_cast<WTW_PARAM>(config), reinterpret_cast<WTW_PARAM>(hInstance));
}

void Manager::initStartActions(){
	wtwMenuItemDef mi;
	initStruct(mi);
	mi.menuID = WTW_MENU_ID_MAIN_OPT;
	mi.hModule = hInstance;
	mi.cbData = static_cast<void*>(this);
	mi.callback = Manager::startBot;
	mi.menuCaption = MENU_ITEM_NAME_START;
	mi.itemID = MENU_ITEM_ID_START;
	wtw->fnCall(WTW_MENU_FUNCTION_ADD, reinterpret_cast<WTW_PARAM>(&mi),0);
}

void Manager::initStopAction(){
	wtwMenuItemDef mi;
	initStruct(mi);
	mi.menuID = WTW_MENU_ID_MAIN_OPT;
	mi.hModule = hInstance;
	mi.cbData = static_cast<void*>(this);
	mi.callback = Manager::stopBot;
	mi.menuCaption = MENU_ITEM_NAME_STOP;
	mi.itemID = MENU_ITEM_ID_STOP;
	wtw->fnCall(WTW_MENU_FUNCTION_ADD, reinterpret_cast<WTW_PARAM>(&mi),0);
}

WTW_PTR Manager::startBot(WTW_PARAM wParam, WTW_PARAM lParam, void* ptr){
	wtwMenuItemDef* menuItem = reinterpret_cast<wtwMenuItemDef*>(wParam);
	wtwMenuPopupInfo* menuInfo = reinterpret_cast<wtwMenuPopupInfo*>(lParam);
	reinterpret_cast<Manager*>(ptr)->handleBotAction(menuItem, menuInfo);
	return 0;
}

WTW_PTR Manager::stopBot(WTW_PARAM wParam, WTW_PARAM lParam, void* ptr){
	wtwMenuItemDef* menuItem = reinterpret_cast<wtwMenuItemDef*>(wParam);
	wtwMenuPopupInfo* menuInfo = reinterpret_cast<wtwMenuPopupInfo*>(lParam);
	reinterpret_cast<Manager*>(ptr)->handleBotAction(menuItem, menuInfo);
	return 0;
}
	
void Manager::handleBotAction(wtwMenuItemDef* menuItem, wtwMenuPopupInfo* menuInfo){
	if(wcsncmp( menuItem->itemID, MENU_ITEM_ID_START,wcslen(MENU_ITEM_ID_START)) == 0 ){
		wtw->fnCall(WTW_MENU_FUNCTION_CLR, reinterpret_cast<WTW_PARAM>(hInstance), 0);
		initStopAction();
		chatHook = wtw->evHook(WTW_ON_PROTOCOL_EVENT, Manager::AutoResponse, (void*)this);
	}else{ 
		if(wcsncmp(menuItem->itemID , MENU_ITEM_ID_STOP,wcslen(MENU_ITEM_ID_STOP)) == 0){
			wtw->evUnhook(chatHook);
			chatHook = 0;
			wtw->fnCall(WTW_MENU_FUNCTION_CLR, reinterpret_cast<WTW_PARAM>(hInstance), 0);
			initStartActions();
		}
	}
}

WTW_PTR Manager::AutoResponse(WTW_PARAM wP, WTW_PARAM lP, void* ptr){
	wtwProtocolEvent *proto = (wtwProtocolEvent *) wP;
	if(proto->event != WTW_PEV_MESSAGE_RECV || proto->type != WTW_PEV_TYPE_BEFORE)
		return 0;
	
	wtwMessageDef *msg = (wtwMessageDef *) lP; 
	wtwMessageDef response;
	initStruct(response);
	response.contactData = msg->contactData;
	response.exResource = msg->exResource;
	response.extInfo = msg->extInfo;
	response.extInfoCount = msg->extInfoCount;
	response.msgFlags =  WTW_MESSAGE_FLAG_CHAT_MSG | WTW_MESSAGE_FLAG_OUTGOING;;
	response.msgSubject = msg->msgSubject;
	response.msgTime = msg->msgTime +1;
	wchar_t _f[300];
	wchar_t* botId;
	wchar_t message[300];
	wtwGetStr(wtw, ((Manager*)ptr)->config,L"botID", L"d304312c4e342d88", &botId);
	Manager* mng = ((Manager*)ptr);
	std::string temp = reply(L"91288c945e3426dc", msg->msgMessage);
	LOG(L"TEMP:");
	LOG(StringToWString(temp).c_str());
	if(strcmp(temp.c_str(), "unknown.")!=0){
		LOG(L"TEMP different");
		mng->humour = temp;
		LOG(L"humour has been changed:");
		LOG(StringToWString(mng->humour).c_str());
	}
	LOG(L"HUMOUR:");
	LOG(StringToWString(mng->humour).c_str());
	if( strcmp(mng->humour.c_str(), "")==0 || strcmp(mng->humour.c_str(), "unknown.")==0){
		mng->humour = temp;
		LOG(L"humour has been changed:");
		LOG(StringToWString(mng->humour).c_str());
	}
	
	swprintf(message, L"%s",getMsgContext(msg, mng->humour));  
	swprintf(message,L"%s%s", message, msg->msgMessage);
	swprintf(message,L"%s", StringToWString( reply(botId, message) ).c_str());
	response.msgMessage = message ;
	wsprintf(_f, L"%s/%d/%s", response.contactData.netClass, response.contactData.netId, WTW_PF_MESSAGE_SEND);
	if(!wtw->fnCall(_f, (WTW_PARAM)response, (WTW_PARAM)ptr)){
		wtw->fnCall(WTW_CHATWND_SHOW_MESSAGE, *msg, 0);
		wtw->fnCall(WTW_CHATWND_SHOW_MESSAGE, response, 0);
		free(botId);
		return BMD_FORCE_NO_DISP;
	}
	
	free(botId);
	return BMD_OK;
}

wchar_t* Manager::getDayPeriod(time_t time){
	struct tm *tm_now;
	tm_now = localtime(&time);
	if(tm_now->tm_hour>=6 && tm_now->tm_hour <= 12)
		return L"morning";
	if(tm_now->tm_hour>12 && tm_now->tm_hour <= 18)
		return L"afternoon";
	if(tm_now->tm_hour>18 && tm_now->tm_hour <= 24)
		return L"evening";
	return L"night";
}
wchar_t* Manager::getMsgContext(wtwMessageDef *msg, std::string humour){
	 wchar_t context[400];
	 
	 swprintf(context,L"%s # %s # %s # ", msg->contactData.id, getDayPeriod(msg->msgTime),  StringToWString( humour.substr(0,humour.length()-1) ).c_str());
	 return context;
 }
void Manager::initOptions(){
	initStruct(settings);
	settings.id = PAGE_NAME;
	settings.caption = L"ChatBot";
	settings.parentID = WTW_OPTIONS_GROUP_PLUGINS;
	settings.callback = Manager::showSettingPage;
	settings.cbData = config;
	wtw->fnCall(WTW_OPTION_PAGE_ADD, reinterpret_cast<WTW_PARAM>(hInstance), reinterpret_cast<WTW_PARAM>(&settings));
}

WTW_PTR Manager::showSettingPage(WTW_PARAM wParam, WTW_PARAM lParam, void* ptr){
	wtwOptionPageShowInfo* info = (wtwOptionPageShowInfo*)wParam; 
	SettingsPage* pOptions = (SettingsPage*)(WTW_PARAM)info->page->ownerData; 
    wcscpy(info->windowCaption, L"Chat Bot"); 
    wcscpy(info->windowDescrip, L"Ustawienia bota"); 
    switch(info->action)  
    { 
    case WTW_OPTIONS_PAGE_ACTION_SHOW:  
        { 
            if(!pOptions) 
            { 
				pOptions = new SettingsPage((HINSTANCE)ptr,info->page->cbData); 
                info->page->ownerData = (void*)pOptions; 
                pOptions->Create(info->handle); 
				RECT rc; 
                pOptions->GetClientRect(&rc); 
				pOptions->SetScrollSize(rc.right - rc.left, rc.top - rc.bottom); 
            } 
            pOptions->MoveWindow(info->x, info->y, info->cx, info->cy, TRUE); 
            pOptions->ShowWindow(SW_SHOW); 
	        break;      
        } 
    case WTW_OPTIONS_PAGE_ACTION_MOVE: 
        { 
            if(pOptions) 
            { 
                pOptions->MoveWindow(info->x, info->y, info->cx, info->cy, TRUE); 
            } 
            break; 
        } 
    case WTW_OPTIONS_PAGE_ACTION_HIDE:  
        { 
            if(pOptions) 
            { 
                pOptions->ShowWindow(SW_HIDE); 
            } 
            break; 
        } 
    case WTW_OPTIONS_PAGE_ACTION_APPLY:  
        { 
            if(pOptions) 
            { 
                pOptions->close(true); 
            } 
            break; 
        } 
    case WTW_OPTIONS_PAGE_ACTION_OK: 
    case WTW_OPTIONS_PAGE_ACTION_CANCEL:  
        { 
            if(pOptions)  
            { 
                pOptions->close(info->action == WTW_OPTIONS_PAGE_ACTION_OK); 
                pOptions->DestroyWindow(); 
                info->page->ownerData = 0; 
                delete pOptions; 
                pOptions = 0; 
            } 
            break; 
        } 
    } 
    return 0; 
}

WTW_PTR Manager::convert(WTW_PARAM wParam, WTW_PARAM lParam, void* ptr){
	return 0;
}